#include "StdAfx.h"
#include "Client.h"
#include "NetClient\Message.h"
CClient::CClient(void)
:m_socket(0)
{
}

CClient::~CClient(void) 
{
}

unsigned int __stdcall WorkFunc(void * prama)
{
	CClient* pClient=(CClient*)prama;
	LPPER_HANDLE_DATA PerHandleData;
	LPPER_IO_OPERATION_DATA PerIoData;
	DWORD dwRecv=0;
	while (true)
	{
		if (GetQueuedCompletionStatus(pClient->m_hCompletionPort,&dwRecv,(LPDWORD)&PerHandleData,
			(LPOVERLAPPED*)&PerIoData,INFINITE)==SOCKET_ERROR)
		{

		}
		if (PerIoData==NULL)
		{
			cout<<"Serious ERROR"<<endl;
			break;
		}
		switch (PerIoData->_OpType)
		{
		case OP_READ:
			{
				cout<<"Server:"<<PerIoData->_cbuffer<<endl;
				DWORD msgType=0;
				memcpy(&msgType,PerIoData->_cbuffer,sizeof(DWORD));
				CMessage* pMsg=new CMessage(1);
				pMsg->SetData((BYTE*)PerIoData->_cbuffer,dwRecv);
				pMsg->SetType(msgType);
				//CMsgQueue::GetMsgQueue()->PushMessage(pMsg);
				pClient->GetMsgQueue()->PushMessage(pMsg);
				

			}
			break;
		case OP_WRITE:
			{
				
			}
			break;
		default:break;
		}

	
		WSABUF wsabuf;

	
		wsabuf.buf=PerIoData->_cbuffer;
		wsabuf.len=DATA_BUFSIZE;
		DWORD Bytes=0,Flags=0;
		PerIoData->_OpType=OP_READ;
		WSARecv(PerHandleData->Socket,&wsabuf,1,&Bytes,&Flags,&PerIoData->Overlapped,
			NULL);
	}
	return 0;
}

SOCKET CClient::Connect(char* strIP,DWORD dwPort)
{
	if (strIP==NULL)
		return false;
	WSADATA wsd;
	WSAStartup( 0x11 , &wsd );

	SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 

	sockaddr_in clientService; 

	clientService.sin_family = AF_INET;
	clientService.sin_addr.s_addr = inet_addr( "10.34.64.55" );
	//clientService.sin_addr.s_addr = inet_addr( "192.168.1.19" );
	clientService.sin_port = htons( 3911 );
	if ( connect( s, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
	{
		GetLastError();
		printf( "Failed to connect.\n" );
		WSACleanup();
		return 0;
	}
	m_MsgQueue.Init();
	SYSTEM_INFO SysInfo;
	GetSystemInfo(&SysInfo);
	HANDLE hCompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,SysInfo.dwNumberOfProcessors);
	if (hCompletionPort==NULL)
		return 0;
	m_hCompletionPort=hCompletionPort;
	for (DWORD i=0;i<SysInfo.dwNumberOfProcessors;i++)
	{
		_beginthreadex(NULL,NULL,WorkFunc,this,0,NULL);
	}
	
	LPPER_HANDLE_DATA PerHandleData=new PER_HANDLE_DATA();
	PerHandleData->Socket=s;
	m_socket=s;
	CreateIoCompletionPort( (HANDLE)s, hCompletionPort,
		(DWORD) PerHandleData,0);
	DWORD RecvBytes=0,Flags=0;
	LPPER_IO_OPERATION_DATA PerIoData=new PER_IO_OPERATION_DATA();
	ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
	PerIoData->_DataBuf.buf = PerIoData->_cbuffer;
	PerIoData->_DataBuf.len = DATA_BUFSIZE;
	int err=WSARecv(s, &PerIoData->_DataBuf, 1,  &RecvBytes, &Flags, 
		&PerIoData->Overlapped, NULL);
	return s;
}

void CClient::SendToSocket(char* buffer,DWORD dwSize)
{
	LPPER_IO_OPERATION_DATA PerIoData=new PER_IO_OPERATION_DATA();
	LPPER_HANDLE_DATA PerHandleData=new PER_HANDLE_DATA();
	PerHandleData->Socket=m_socket;

	ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED)); 
	
	PerIoData->_DataBuf.buf=buffer;
	PerIoData->_DataBuf.len=strlen(buffer);
	strcpy(PerIoData->_cbuffer,buffer);
	PerIoData->_OpType=OP_WRITE;
	DWORD SendBytes=0;
	WSASend(PerHandleData->Socket, &(PerIoData->_DataBuf), 1, &SendBytes, 0, 
		&(PerIoData->Overlapped), NULL);
}